package com.yida.system.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yida.common.core.constant.CacheConstants;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.request.SmsRequest;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.HttpApiUtil;
import com.yida.common.core.utils.ServletUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.core.utils.ip.IpUtils;
import com.yida.common.redis.service.RedisService;
import com.yida.system.api.constants.EsbRequestLogConstants;
import com.yida.system.api.constants.InterfaceCodeConstants;
import com.yida.system.api.domain.EsbRequestLog;
import com.yida.system.api.domain.SysSms;
import com.yida.system.api.enums.SysDataPutInConfigEnum;
import com.yida.system.api.vo.SysDataPutInInterfaceVO;
import com.yida.system.mapper.EsbRequestLogMapper;
import com.yida.system.mapper.SysSmsMapper;
import com.yida.system.service.ISysLocalSmsService;
import com.yida.system.service.ISysSmsService;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;

/**
 * 手机短信记录Service业务层处理
 * 
 * @author hmh
 * @date 2022-10-26
 */
@Service
public class SysSmsServiceImpl implements ISysSmsService {

    private Long smsCodeExpiration = CacheConstants.SMS_CODE_EXPIRATION;

    // 验证码是否前端参数返回显示
    private final String isPhoneCodeFront = "sys.phonenumber.codeFrontEnabled";

    // 验证码发送是否使用ESB系统
    private final String isEsbSendSms = "sys.phonenumber.esbSendSmsEnabled";

    // 系统挡板开关
    private final String sysDataBaffleStatus = CacheConstants.SYS_DATA_BAFFLE_STATUS;

    @Autowired
    private SysSmsMapper sysSmsMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private EsbRequestLogMapper esbRequestLogMapper;

    @Autowired
    private ISysLocalSmsService iSysLocalSmsService;

    /**
     * 查询手机短信记录
     * 
     * @param smsId 手机短信记录主键
     * @return 手机短信记录
     */
    @Override
    public SysSms selectSysSmsBySmsId(Long smsId) {
        return sysSmsMapper.selectSysSmsBySmsId(smsId);
    }

    /**
     * 查询手机短信记录列表
     * 
     * @param sysSms 手机短信记录
     * @return 手机短信记录
     */
    @Override
    public List<SysSms> selectSysSmsList(SysSms sysSms) {
        return sysSmsMapper.selectSysSmsList(sysSms);
    }

    /**
     * 新增手机短信记录
     * 
     * @param sysSms 手机短信记录
     * @return 结果
     */
    @Override
    public int insertSysSms(SysSms sysSms) {
        sysSms.setCreateTime(DateUtils.getNowDate());
        return sysSmsMapper.insertSysSms(sysSms);
    }

    @Override
    public int insertSysSms(SysSms sysSms, Long smsCodeExpiration) {
        Date date = DateUtils.getNowDate();
        sysSms.setCreateTime(date);
        if (smsCodeExpiration == 0 || smsCodeExpiration == null) {
            smsCodeExpiration = this.smsCodeExpiration;
        }
        sysSms.setExpireTime(DateUtils.addMinutes(date, smsCodeExpiration.intValue()));
        return sysSmsMapper.insertSysSms(sysSms);
    }

    /**
     * 修改手机短信记录
     * 
     * @param sysSms 手机短信记录
     * @return 结果
     */
    @Override
    public int updateSysSms(SysSms sysSms) {
        return sysSmsMapper.updateSysSms(sysSms);
    }

    /**
     * 批量删除手机短信记录
     * 
     * @param smsIds 需要删除的手机短信记录主键
     * @return 结果
     */
    @Override
    public int deleteSysSmsBySmsIds(Long[] smsIds) {
        return sysSmsMapper.deleteSysSmsBySmsIds(smsIds);
    }

    /**
     * 删除手机短信记录信息
     * 
     * @param smsId 手机短信记录主键
     * @return 结果
     */
    @Override
    public int deleteSysSmsBySmsId(Long smsId) {
        return sysSmsMapper.deleteSysSmsBySmsId(smsId);
    }

    /* 
     * 发送短信验证码
     */
    @Override
    public SysSms sendSms(String phonenumber) {
        // 生成六位随机码
        String mathCode = RandomUtil.randomNumbers(6);
        // 调用接口发送短信
        // TODO 未对接
        SysSms sysSms = new SysSms();
        sysSms.setPhonenumber(phonenumber);
        sysSms.setSms(mathCode);
        sysSms.setSmsType(1);
        sysSms.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
        // 存储记录并返回
        insertSysSms(sysSms, smsCodeExpiration);
        return sysSms;
    }

    /*
     * 自定义短信发送
     * 
     */
    @Override
    public SysSms sendSms(SysSms sysSms) {
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        sysSms.setIpaddr(ip);
        sysSms.setIpLocal(IpUtils.getRealAddress(ip));
        if (sysSms.getSmsType() == null) {
            // 默认其他
            sysSms.setSmsType(0);
        }
        if (sysSms.getSmsType() == 1) {
            // 生成六位随机码
            String mathCode = RandomUtil.randomNumbers(6);
            sysSms.setSms(mathCode);
        }
        // 调用接口发送短信
        sendSmsMsg(sysSms);

        // 存储记录并返回
        insertSysSms(sysSms, smsCodeExpiration);
        return sysSms;
    }

    /* 
     * 预留不做处理
     */
    @Override
    public int verifySms(SysSms sysSms, int type) {
        // TODO Auto-generated method stub
        return 0;
    }

    /**
     * 根据手机号和短信类型删除记录
     */
    @Override
    public int deleteSysSmsByPhonenumber(String phonenumber, Integer type) {
        return sysSmsMapper.deleteSysSmsByPhonenumber(phonenumber, type);
    }

    @Override
    public int cleanSmsInfo() {
        return sysSmsMapper.cleanSmsInfo();
    }

    /* 
     * 根据手机号和短信类型删除记录
     */
    @Override
    public int deleteSysSmsByPhonenumber(String phonenumber, Integer type, String smsSource) {
        return sysSmsMapper.deleteSysSmsByPhonenumberAndSmsSource(phonenumber, type, smsSource);
    }

    // ---------------------------新功能保留区-----------------------------------------
    /* 
     * 自定义服务短信发送
     */
    @Override
    public SysSms sendInnerSms(SysSms sysSms) {
        // 从缓存中获取验证码
        String redisSmsKey = getSmsCacheKey(sysSms.getSmsSource() + ":" + sysSms.getPhonenumber());
        String redisSmsVaule = redisService.getCacheObject(redisSmsKey);
        // 不为空则存在有效期
        if (StringUtils.isNotEmpty(redisSmsVaule)) {
            throw new ServiceException("[" + sysSms.getPhonenumber() + "]两次发送间隔未超过" + CacheConstants.SMS_CODE_EXPIRATION + "分钟，请不要重复发送！");
        }
        // 校验通过进行参数配置
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        sysSms.setIpaddr(ip);
        sysSms.setIpLocal(IpUtils.getRealAddress(ip));
        if (sysSms.getSmsType() == null) {
            // 默认其他
            sysSms.setSmsType(0);
        }
        if (sysSms.getSmsType() == 1) {
            // 生成六位随机码
            String mathCode = RandomUtil.randomNumbers(6);
            sysSms.setSms(mathCode);
        }

        // 发送短信
        sendSmsMsg(sysSms);

        // 设置短信缓存
        Long activeTime = sysSms.getActiveTime();
        if (StringUtils.isNull(activeTime) || activeTime <= 0) {
            activeTime = CacheConstants.SMS_CODE_EXPIRATION;
        }
        // 设置当前短信内容有效期
        redisService.setCacheObject(redisSmsKey, sysSms.getSms(), activeTime, TimeUnit.MINUTES);
        // 存储记录并返回
        insertSysSms(sysSms, smsCodeExpiration);
        // 替换短信内容
        replaceSmsMsg(sysSms);
        return sysSms;
    }

    /**
     * 设置cache key
     * 
     * @param configKey 参数键
     * @return 缓存键key
     */
    public String getSmsCacheKey(String configKey) {
        return CacheConstants.SMS_CODE_EXPIRATION_KEY + configKey;
    }

    /**
     * 替换短信内容为默认值
     * 
     * @param sysSms
     */
    private void replaceSmsMsg(SysSms sysSms) {
        // 获取显示设置
        String codeFrontEnabled = redisService.getCacheObject(getCacheKey(isPhoneCodeFront));
        if (StringUtils.isBlank(codeFrontEnabled)) {
            codeFrontEnabled = "true";
        }
        // 否情况下进行数据替换 20231107
        if ("false".equals(codeFrontEnabled)) {
            sysSms.setSms("ok");
        }
    }

    /**
     * 短信发送
     * 
     * hmh
     * 
     * 20231101
     * 
     * 改造适配远程ESB及本地发送状态切换，避免部署环境无ESB情况发生
     * 
     * @param sysSms
     */
    private void sendSmsMsg(SysSms sysSms) {
        Long semExpirationTime = NumberUtils.toLong(getCacheKey(CacheConstants.SMS_CODE_EXPIRATION_TIME_KEY));
        sysSms.setActiveTime(semExpirationTime > 0 ? semExpirationTime : smsCodeExpiration);
        // 20231107 如果使用挡板，则不进行发送操作
        if (checkDataBaffleStatus()) {
            return;
        }
        String esbSendSmsEnabled = redisService.getCacheObject(getCacheKey(isEsbSendSms));
        // 默认不启用
        if (StringUtils.isBlank(esbSendSmsEnabled)) {
            esbSendSmsEnabled = "false";
        }
        // 开启则使用远程esb系统发送
        if ("true".equals(esbSendSmsEnabled)) {
            sendSmsMsgByEsb(sysSms);
            return;
        }
        // 否则默认使用本地系统发送短信
        iSysLocalSmsService.sendSms(sysSms);
    }

    private void sendSmsMsgByEsb(SysSms sysSms) {
        // 临时 启用状态 进行短信发送
        if (checkDataBaffleStatus()) {
            return;
        }
        // 查询配置信息
        String key = CacheConstants.SYS_DATA_PUT_IN + CacheConstants.REDIS_SUFFIX + SysDataPutInConfigEnum.GWJ_SMS_CONFIG.getType() + CacheConstants.REDIS_SUFFIX + InterfaceCodeConstants.SMS_INTERFACE_CODE;
        SysDataPutInInterfaceVO sysDataPutInInterfaceVO = redisService.getCacheObject(key);
        if (ObjectUtil.isEmpty(sysDataPutInInterfaceVO)) {
            throw new ServiceException("未配置数据接入接口配置");
        }
        List<String> mobileList = new ArrayList<>();
        List<String> contentList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(sysSms.getPhonenumber()) && ObjectUtil.isNotEmpty(sysSms.getSms())) {
            mobileList.add(sysSms.getPhonenumber());
            contentList.add(sysSms.getSms());
        } else if (ObjectUtil.isNotEmpty(sysSms.getPhonenumberList()) && ObjectUtil.isNotEmpty(sysSms.getSmsList())) {
            mobileList.addAll(sysSms.getPhonenumberList());
            contentList.addAll(sysSms.getSmsList());
        } else {
            throw new ServiceException("号码不能为空");
        }
        // 设置请求参数
        SmsRequest request = new SmsRequest();
        request.setDockingInterfaceConfigId(sysDataPutInInterfaceVO.getDockingInterfaceConfigId());
        request.setRequestFlag("test-group");
        request.setSmsTemplateId("");
        request.setScheduleTime(null);
        request.setMobileList(mobileList);
        request.setContentList(contentList);
        request.setCompanyId(sysDataPutInInterfaceVO.getCompanyId());
        // 发送请求
        String result = HttpApiUtil.sendSmsPostRequest(sysDataPutInInterfaceVO.getIpUrl() + sysDataPutInInterfaceVO.getInterfaceUri(), request);
        // 新增企业总线请求日志
        EsbRequestLog esbRequestLog = new EsbRequestLog();
        esbRequestLog.setUrl(sysDataPutInInterfaceVO.getIpUrl() + sysDataPutInInterfaceVO.getInterfaceUri());
        esbRequestLog.setRequestParams(JSONUtil.toJsonStr(request));
        esbRequestLog.setTitle(EsbRequestLogConstants.PULL_GWJ_DATA);
        esbRequestLog.setDockingInterfaceConfigId(sysDataPutInInterfaceVO.getDockingInterfaceConfigId());
        esbRequestLog.setResponse(result);
        esbRequestLog.setResponeId(String.valueOf(JSONUtil.parseObj(result).get(EsbRequestLogConstants.RESPONSE_ID)));
        esbRequestLogMapper.insertEsbRequestLog(esbRequestLog);
    }

    // 临时，后期调整
    private boolean checkDataBaffleStatus() {
        // 获取显示设置
        String dataBaffleStatus = redisService.getCacheObject(getCacheKey(sysDataBaffleStatus));
        if (StringUtils.isBlank(dataBaffleStatus)) {
            return false;
        }
        if ("true".equals(dataBaffleStatus)) {
            return true;
        }
        return false;
    }

    /**
     * 设置cache key
     * 
     * @param configKey 参数键
     * @return 缓存键key
     */
    public String getCacheKey(String configKey) {
        return CacheConstants.SYS_CONFIG_KEY + configKey;
    }

    // ---------------------------新功能保留区-----------------------------------------
}
